/*
  one Table equals one table of mysql.
  this.tableName equals table name
  
  table:{
    metadata: {
      length : x,
      name: tableName,
    }
  },{
    id1: {id: id1, field1: value1; field2: value2}
  },{
    id2: {id: id2, field1: value1; field2: value2}
  },..
  
  
  actionName: is service side action name
  period:　sync per peroid
*/
Table = function(tableName, actionName, period){
  this.tableName = tableName;
  this.actionName = actionName;
  this.period = period;
  
  console.log(this.tableName + " upload last unsynced data");
  this.push(function(){
    this.schedulePush();
  }.bind(this));
};


/*
  save record locally
  record: one row of table
*/
Table.prototype.commit = function(record){
  this.saveRecord(record);
};

/*
  upload local data onto server side,
  after uploading, all data are synced, and local data removed
*/
Table.prototype.push = function(callback){
  console.log(this.tableName + ': To push records');
  chrome.storage.local.get(this.tableName, function(db){
    var table = db[this.tableName];
    var data = [];
    for(var id in table){
      if(id != 'metadata'){ //exclude metadata
        rec = table[id];
        data.push(rec);
      }
    }
    var tableName = this.tableName;
    if(data.length){
      console.log(this.tableName + ": Start to upload " + data.length + " unsynced records");
      ajax.doPost(this.actionName, data, 
        function(response){
          if(response == 1){
            console.log(tableName + ': Synced records');
            if(callback) callback(true);
            db[tableName] = {};
            chrome.storage.local.set(db, function(){
              console.log(tableName + ': Cleared records locally');
            });
          }
        }, 
        function(response){
          console.log(tableName + ': Sync failure: ' + response);
          if(callback) callback(false);
        }
      );
    }else{
      console.log(this.tableName + ": No data to sync");
      if(callback) callback(false);
    }
    
  }.bind(this));
};

/*
  start a schedul to push local data onto server
*/
Table.prototype.schedulePush = function(){
  console.log(this.tableName + ": Schedule to upload " + this.tableName + " " + this.period / 1000 / 60 + " minutes later");
  var me = this;
  setTimeout(function(){
    me.push(function(){
      me.schedulePush();
    });
  }, this.period);
};

/*********************************start CRUD***************************************/
Table.prototype.getRecord = function(id, callback){
  chrome.storage.local.get(this.tableName, function(db){
    var table = db[this.tableName];
    callback(table[id]);
  }.bind(this));
};

Table.prototype.saveRecord = function(record){
  console.log(this.tableName + ': To save record: ' + record.id);
  chrome.storage.local.get(this.tableName, function(db){
    var table = db[this.tableName];
    if(!table || !table.metadata){
      table = {
        metadata: {
          length: 0,
          name: this.tableName
        }
      };
      db[this.tableName] = table;
    }
    var rec = table[record.id];
    if(!rec){
      //add new one, update length
      table.metadata.length ++;
    }
    table[record.id] = record;
    
    chrome.storage.local.set(db, function(){
      console.log(this.tableName + ': Saved record: ' + record.id);
    }.bind(this));
  }.bind(this)); 
};

Table.prototype.deleteRecord = function(record){
  chrome.storage.local.get(this.tableName, function(db){
    var table = db[this.tableName];
    var rec = table[record.id];
    if(rec){
      //update length
      this.metadata.length --;
      delete this[record.id];
    }
    chrome.storage.local.set(db, function(){
      console.log(this.tableName + ': Deleted record: ' + record.id);
    }.bind(this));
  }.bind(this)); 
};
/*********************************end   CRUD***************************************/
